package com.tools.utils;


import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 摩斯密码转换工具类
 * 支持中文、数字、字母与摩斯密码之间的互相转换
 */
public class MorseCodeUtil {

    // 字符到摩斯密码的映射表
    private static final Map<Character, String> CHAR_TO_MORSE = new HashMap<>();

    // 摩斯密码到字符的映射表
    private static final Map<String, Character> MORSE_TO_CHAR = new HashMap<>();

    // 分隔符定义
    public static final String CHAR_SEPARATOR = " ";       // 字符之间的分隔符
    public static final String CHINESE_SEPARATOR = "|";    // 中文字符之间的分隔符
    public static final String WORD_SEPARATOR = "/";       // 单词之间的分隔符
    public static final String HEX_ESCAPE = "\\";          // 十六进制转义符

    // 静态初始化映射表
    static {
        // 初始化字母A-Z的摩斯密码
        CHAR_TO_MORSE.put('A', ".-");
        CHAR_TO_MORSE.put('B', "-...");
        CHAR_TO_MORSE.put('C', "-.-.");
        CHAR_TO_MORSE.put('D', "-..");
        CHAR_TO_MORSE.put('E', ".");
        CHAR_TO_MORSE.put('F', "..-.");
        CHAR_TO_MORSE.put('G', "--.");
        CHAR_TO_MORSE.put('H', "....");
        CHAR_TO_MORSE.put('I', "..");
        CHAR_TO_MORSE.put('J', ".---");
        CHAR_TO_MORSE.put('K', "-.-");
        CHAR_TO_MORSE.put('L', ".-..");
        CHAR_TO_MORSE.put('M', "--");
        CHAR_TO_MORSE.put('N', "-.");
        CHAR_TO_MORSE.put('O', "---");
        CHAR_TO_MORSE.put('P', ".--.");
        CHAR_TO_MORSE.put('Q', "--.-");
        CHAR_TO_MORSE.put('R', ".-.");
        CHAR_TO_MORSE.put('S', "...");
        CHAR_TO_MORSE.put('T', "-");
        CHAR_TO_MORSE.put('U', "..-");
        CHAR_TO_MORSE.put('V', "...-");
        CHAR_TO_MORSE.put('W', ".--");
        CHAR_TO_MORSE.put('X', "-..-");
        CHAR_TO_MORSE.put('Y', "-.--");
        CHAR_TO_MORSE.put('Z', "--..");

        // 初始化数字0-9的摩斯密码
        CHAR_TO_MORSE.put('0', "-----");
        CHAR_TO_MORSE.put('1', ".----");
        CHAR_TO_MORSE.put('2', "..---");
        CHAR_TO_MORSE.put('3', "...--");
        CHAR_TO_MORSE.put('4', "....-");
        CHAR_TO_MORSE.put('5', ".....");
        CHAR_TO_MORSE.put('6', "-....");
        CHAR_TO_MORSE.put('7', "--...");
        CHAR_TO_MORSE.put('8', "---..");
        CHAR_TO_MORSE.put('9', "----.");

        // 初始化一些特殊字符
        CHAR_TO_MORSE.put(' ', WORD_SEPARATOR);
        CHAR_TO_MORSE.put('.', ".-.-.-");
        CHAR_TO_MORSE.put(',', "--..--");
        CHAR_TO_MORSE.put('?', "..--..");
        CHAR_TO_MORSE.put('\'', ".----.");
        CHAR_TO_MORSE.put('!', "-.-.--");
        CHAR_TO_MORSE.put('/', "-..-.");
        CHAR_TO_MORSE.put('(', "-.--.");
        CHAR_TO_MORSE.put(')', "-.--.-");
        CHAR_TO_MORSE.put('&', ".-...");
        CHAR_TO_MORSE.put(':', "---...");
        CHAR_TO_MORSE.put(';', "-.-.-.");
        CHAR_TO_MORSE.put('=', "-...-");
        CHAR_TO_MORSE.put('+', ".-.-.");
        CHAR_TO_MORSE.put('-', "-....-");
        CHAR_TO_MORSE.put('_', "..--.-");
        CHAR_TO_MORSE.put('"', ".-..-.");
        CHAR_TO_MORSE.put('$', "...-..-");
        CHAR_TO_MORSE.put('@', ".--.-.");
        CHAR_TO_MORSE.put('\\', "-..-."); // 转义符的摩斯密码表示
        CHAR_TO_MORSE.put('|', "-.-.-");  // 中文分隔符的摩斯密码表示

        // 构建反向映射（摩斯密码到字符）
        for (Map.Entry<Character, String> entry : CHAR_TO_MORSE.entrySet()) {
            MORSE_TO_CHAR.put(entry.getValue(), entry.getKey());
        }
    }

    /**
     * 将中文转换为摩斯密码
     */
    public static String chineseToMorse(String chinese) {
        if (chinese == null || chinese.isEmpty()) {
            return "";
        }

        StringBuilder result = new StringBuilder();

        for (char c : chinese.toCharArray()) {
            // 检查是否是ASCII字符
            if (c <= 127) {
                // 直接转换ASCII字符
                String morse = CHAR_TO_MORSE.get(Character.toUpperCase(c));
                // 对于无法识别的ASCII字符，添加标记
                result.append(Objects.requireNonNullElse(morse, "[?]")).append(CHAR_SEPARATOR);
            } else {
                // 处理中文字符：添加转义符
                String escapeMorse = CHAR_TO_MORSE.get(HEX_ESCAPE.charAt(0));
                if (escapeMorse != null) {
                    result.append(escapeMorse).append(CHAR_SEPARATOR);
                }

                // 转换为UTF-8字节的十六进制表示
                byte[] bytes = String.valueOf(c).getBytes(StandardCharsets.UTF_8);
                for (byte b : bytes) {
                    // 转换每个字节为两个十六进制字符
                    char[] hexChars = String.format("%02X", b).toCharArray();
                    for (char hexChar : hexChars) {
                        String morse = CHAR_TO_MORSE.get(hexChar);
                        result.append(Objects.requireNonNullElse(morse, "[?]")).append(CHAR_SEPARATOR);
                    }
                }

                // 添加中文字符结束标记
                String separatorMorse = CHAR_TO_MORSE.get(CHINESE_SEPARATOR.charAt(0));
                if (separatorMorse != null) {
                    result.append(separatorMorse).append(CHAR_SEPARATOR);
                }
            }
        }

        // 移除最后一个分隔符
        if (!result.isEmpty()) {
            result.setLength(result.length() - CHAR_SEPARATOR.length());
        }

        return result.toString();
    }

    /**
     * 将摩斯密码转换为中文
     */
    public static String morseToChinese(String morse) {
        if (morse == null || morse.isEmpty()) {
            return "";
        }

        // 分割摩斯密码为单个字符的摩斯码
        String[] morseParts = morse.split(CHAR_SEPARATOR);
        StringBuilder result = new StringBuilder();
        boolean inChineseHex = false;  // 是否正在处理中文字符的十六进制表示
        StringBuilder chineseHexBuilder = new StringBuilder();

        for (String part : morseParts) {
            if (part.isEmpty() || "[?]".equals(part)) {
                continue;
            }

            // 尝试直接转换为字符
            Character c = MORSE_TO_CHAR.get(part);

            // 检查是否是中文字符的开始标记（转义符）
            if (c != null && HEX_ESCAPE.charAt(0) == c) {
                inChineseHex = true;
                chineseHexBuilder.setLength(0);
                continue;
            }

            // 检查是否是中文字符的结束标记
            if (c != null && CHINESE_SEPARATOR.charAt(0) == c) {
                inChineseHex = false;
                // 转换累积的十六进制字符串为中文字符
                if (!chineseHexBuilder.isEmpty()) {
                    try {
                        String hexStr = chineseHexBuilder.toString();
                        // 确保十六进制字符串长度为偶数
                        if (hexStr.length() % 2 != 0) {
                            throw new IllegalArgumentException("无效的十六进制长度");
                        }

                        byte[] bytes = new byte[hexStr.length() / 2];
                        for (int i = 0; i < bytes.length; i++) {
                            int index = i * 2;
                            int value = Integer.parseInt(hexStr.substring(index, index + 2), 16);
                            bytes[i] = (byte) value;
                        }

                        // 将字节数组转换为中文字符
                        result.append(new String(bytes, StandardCharsets.UTF_8));
                    } catch (Exception e) {
                        result.append("[无效中文: ").append(chineseHexBuilder).append("]");
                    }
                    chineseHexBuilder.setLength(0);
                }
                continue;
            }

            // 如果正在处理中文字符的十六进制表示
            if (inChineseHex) {
                if (c != null && (Character.isDigit(c) || (c >= 'A' && c <= 'F'))) {
                    chineseHexBuilder.append(c);
                } else {
                    // 无效的十六进制字符
                    inChineseHex = false;
                    result.append("[无效字符: ").append(part).append("]");
                    chineseHexBuilder.setLength(0);
                }
                continue;
            }

            // 处理普通字符
            if (c != null) {
                // 如果是单词分隔符，添加空格
                if (WORD_SEPARATOR.equals(part)) {
                    result.append(' ');
                } else {
                    result.append(c);
                }
            } else {
                // 无法识别的摩斯码
                result.append("[无法识别: ").append(part).append("]");
            }
        }

        // 处理未正常结束的中文字符解析
        if (inChineseHex) {
            result.append("[未结束的中文: ").append(chineseHexBuilder).append("]");
        }

        return result.toString();
    }

    // 测试方法
    public static void main(String[] args) {
        // 测试数字转换
        String numbers = "1234567890";
        System.out.println("原始数字: " + numbers);

        String morseNumbers = chineseToMorse(numbers);
        System.out.println("转换为摩斯密码: " + morseNumbers);

        String decodedNumbers = morseToChinese(morseNumbers);
        System.out.println("解码结果: " + decodedNumbers);
        System.out.println("数字转换是否正确: " + numbers.equals(decodedNumbers));

        // 测试中英文混合
        String mixed = "凌月";
        System.out.println("\n原始字符串: " + mixed);

        String morseMixed = chineseToMorse(mixed);
        System.out.println("转换为摩斯密码: " + morseMixed);

        String decodedMixed = morseToChinese(morseMixed);
        System.out.println("解码结果: " + decodedMixed);
        System.out.println("混合转换是否正确: " + mixed.equals(decodedMixed));
    }
}